package com.example.demo1;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 案例一：查找幸存者(面向对象版)
 */
public class Test1 {
    public static void main(String[] args) {
        // 需求：目前有100名囚犯,每个囚犯的编号是1-200之间的随机数现在要求依次随机生成100名囚犯的编号(要求这些囚犯的编号是不能重复的)
        // 然后让他们依次站成一排(注：位置是从1开始计数的),接下来,国王命令手下先干掉全部奇数位置处的人剩下的人,又从新按位置1开始,
        // 再次干掉全部奇数位置处的人,依此类推,直到最后剩下一个人为止,剩下的这个人为幸存者

        // 1.创建一个集合存储100名囚犯
        List<People> peoples = new ArrayList<>();

        // 2.循环100次创建100个囚犯,存入集合
        Random r = new Random();
        for (int i = 1; i <= 100; i++) {
            // 3.生成1-200之间的随机数,确保每次生成的随机数不能重复
            int index = r.nextInt(200) + 1;
            // 4.在添加随机数之前先去判断是否重复
            if (exist(peoples, index)) {
                // 5.说明当前的随机数重复了,所以需要重新随机 并且i-- 重新本次循环
                i--;
                continue;
            }
            // 6.说明当前的随机数没有重复,直接创建People对象存入集合
            People people = new People(index, i);
            peoples.add(people);
        }

        peoples.forEach(System.out::println);

        // 7.反复删除奇数位置的人,直到集合中只剩下一个人为止
        while (peoples.size() > 1) {
            // 8.干掉奇数位置的人:就是留下偶数位置的人
            // 创建一个临时集合用户存储奇数位置的人
            List<People> tempPeoples = new ArrayList<>();
            // 9.循环遍历所有奇数位置的人,加入到临时集合当中
            for (int i = 1; i < peoples.size(); i += 2) {
                People people = peoples.get(i);
                tempPeoples.add(people);
            }
            // 10.当循环结束后,在把临时集合赋值给 prisoner,继续下一轮循环,直到只剩下一个人为止
            peoples = tempPeoples;
        }

        // 11.取出剩下的唯一一个 prisoner
        People luckPeople = peoples.get(0);
        System.out.println("幸存者编号是：" + luckPeople.getId() + ",位置是：" + luckPeople.getLocation());
    }

    /**
     * 判断生成的编号是否重复
     *
     * @param peoples 囚犯集合
     * @param index   生成的编号
     * @return 返回true 表示重复,返回false表示不重复
     */
    private static boolean exist(List<People> peoples, int index) {
        for (People people : peoples) {
            if (people.getId() == index) {
                return true;
            }
        }
        return false;
    }
}
